/******************************************************************************* * Copyright (c) 2000, 2008 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.jdt.internal.corext.refactoring.typeconstraints.types; import org.eclipse.core.runtime.Assert; import org.eclipse.jdt.core.dom.ITypeBinding; public final class ArrayType extends TType { private TType fElementType; private int fDimensions; private TType fErasure; protected ArrayType(TypeEnvironment environment) { super(environment); } protected ArrayType(TypeEnvironment environment, String key) { super(environment, key); } protected void initialize(ITypeBinding binding, TType elementType) { Assert.isTrue(binding.isArray()); super.initialize(binding); fElementType= elementType; fDimensions= binding.getDimensions(); if (fElementType.isStandardType() || fElementType.isGenericType() || fElementType.isPrimitiveType()) { fErasure= this; } else { fErasure= getEnvironment().create(binding.getErasure()); } } protected void initialize(TType elementType, int dimensions) { fElementType= elementType; fDimensions= dimensions; if (fElementType.isStandardType() || fElementType.isGenericType() || fElementType.isPrimitiveType()) { fErasure= this; } else { fErasure= getEnvironment().createArrayType(elementType.getErasure(), dimensions); } } public TType getElementType() { return fElementType; } /** * Returns the component type of this array. * If getDimensions() is 1, the component type is the element type. * If getDimensions() is > 1, the component type is an array type * with element type getElementType() and dimensions getDimensions() - 1. * * @return the component type */ public TType getComponentType() { if (fDimensions > 1) return getEnvironment().createArrayType(fElementType, fDimensions - 1); else return fElementType; } public int getDimensions() { return fDimensions; } public int getKind() { return ARRAY_TYPE; } public TType[] getSubTypes() { TType[] subTypes= fElementType.getSubTypes(); TType[] result= new TType[subTypes.length]; for (int i= 0; i < subTypes.length; i++) { result[i]= getEnvironment().createArrayType(subTypes[i], fDimensions); } return result; } public TType getErasure() { return fErasure; } public boolean doEquals(TType other) { ArrayType arrayType= (ArrayType)other; return fElementType.equals(arrayType.fElementType) && fDimensions == arrayType.fDimensions; } public int hashCode() { return fElementType.hashCode() << ARRAY_TYPE_SHIFT; } protected boolean doCanAssignTo(TType lhs) { switch (lhs.getKind()) { case NULL_TYPE: return false; case VOID_TYPE: return false; case PRIMITIVE_TYPE: return false; case ARRAY_TYPE: return canAssignToArrayType((ArrayType)lhs); case GENERIC_TYPE: return false; case STANDARD_TYPE: return isArrayLhsCompatible(lhs); case PARAMETERIZED_TYPE: return false; case RAW_TYPE: return false; case UNBOUND_WILDCARD_TYPE: case EXTENDS_WILDCARD_TYPE: case SUPER_WILDCARD_TYPE: return ((WildcardType)lhs).checkAssignmentBound(this); case TYPE_VARIABLE: return false; case CAPTURE_TYPE: return ((CaptureType)lhs).checkLowerBound(lhs); } return false; } private boolean canAssignToArrayType(ArrayType lhs) { if (fDimensions == lhs.fDimensions) { // primitive type don't have any conversion for arrays. if (fElementType.getKind() == PRIMITIVE_TYPE || lhs.fElementType.getKind() == PRIMITIVE_TYPE) return fElementType.isTypeEquivalentTo(lhs.fElementType); return fElementType.canAssignTo(lhs.fElementType); } if (fDimensions < lhs.fDimensions) return false; return isArrayLhsCompatible(lhs.fElementType); } private boolean isArrayLhsCompatible(TType lhsElementType) { return lhsElementType.isJavaLangObject() || lhsElementType.isJavaLangCloneable() || lhsElementType.isJavaIoSerializable(); } protected String getPlainPrettySignature() { StringBuffer result= new StringBuffer(fElementType.getPlainPrettySignature()); for (int i= 0; i < fDimensions; i++) { result.append("[]"); //$NON-NLS-1$ } return result.toString(); } public String getName() { StringBuffer result= new StringBuffer(fElementType.getName()); for (int i= 0; i < fDimensions; i++) { result.append("[]"); //$NON-NLS-1$ } return result.toString(); } }